#!/usr/bin/python
#This file handles the actions related to the Nepomuk SideBar
import sys
sys.path.append(PATH_CONTENT)

import logging
logger = logging.getLogger("NepomukSideBar")

logger.debug("Script neposbar.py in the position")

from constants import PIMO_GROUNDINGOCCURRENCE, NFO_WEBSITE
from the_nepomuk_whisperer import TheNepomukWhisperer
	
current_url = window.content.document.location.href
document.NEPO = TheNepomukWhisperer()

#Use the component to handle some event
event_handler = components.classes["@mozilla.org/EventHandlers;1"].getService(components.interfaces.nsIEventHandlers)
###############################Execute query######################################
def execute():
	myQuery = document.getElementById("queryText").value
	theResult = document.getElementById("queryResult")
	queryResult = document.NEPO.nao.runQuery(myQuery)

	myResultList = document.getElementById("queryResult")	
	#Refresh the List display
	while myResultList.childNodes.length != 0:
		myResultList.removeChild(myResultList.lastChild)
	
	colms = queryResult["variables"]
	head = document.createElement('listhead')
	for colm in colms:
		header = document.createElement('listheader')
		header.setAttribute('label', colm)
		head.appendChild(header)
	myResultList.appendChild(head);
	for elem in queryResult["results"]:
		row = document.createElement('listitem')
		for unit in elem:
			cell = document.createElement('listcell')
			cell.setAttribute('label', unit)
			row.appendChild(cell)
			print unit
		myResultList.appendChild(row);
###############################Deal with rating######################################
#control the stars, which indecate the rate level
def saveRate(SBimageId):
   #Get the rate number
   rateNumInt = int(SBimageId[6])+1
   print rateNumInt

   for i in range(10):
      starFileName = "star"
      if i < rateNumInt:
         starFileName += "Light"
      else:
         starFileName += "Dark"
      if i % 2 == 0:
         starFileName += "L"
      else:
         starFileName += "R"
      starId = "SBstar%s" %i
      document.getElementById(starId).setAttribute('src', 'chrome://nepomuk/content/images/%s.png' % starFileName)

   rateNumStr = str(rateNumInt)

   print "Going to rate for page '%s' with '%s', which title is '%s'" % (window.content.document.location.href,rateNumStr,window.content.document.title)
   
   document_uri = document.NEPO.interface.getAntecedent(PIMO_GROUNDINGOCCURRENCE, window.content.document.location.href)
   if document_uri != None:
   	logger.debug("The document %s has %s as its grounding0currence." % (document_uri, window.content.document.location.href))
   else:
   	logger.debug("""The page "%s"has no grounding0ccurence, creating one.""" % current_url)
   	document_uri = document.NEPO.interface.registerAndReify(window.content.document.location.href, NFO_WEBSITE, window.content.document.title)

   document.NEPO.nao.setNumericRating(document_uri,rateNumStr)

   event_handler.refreshPageInfo(window.content.document.location.href, window.top.document)
   
###############################Common functions######################################   
   
def ClearProList():
	print "ClearProList() in neposbar.py is on duty."
	mylist = document.getElementById("propList")
	while mylist.childNodes.length != 1:
		mylist.removeChild(mylist.lastChild)
	
###############################Deal with Tag Managerment######################################
	
def getProps():
	
	current_url = window.content.document.location.href
	mylist = document.getElementById("propList")
	
	document_uri = document.NEPO.interface.getAntecedent(PIMO_GROUNDINGOCCURRENCE, current_url)
	if document_uri == None:
		return 1
	
	props = document.NEPO.pimo.getAllPropertiesForResource(document_uri)
	#Refresh the Tree display
	ClearProList()		
	for prop in props:
		
		(myPropUri, myProp, myValueUri, myValue) = prop
		row = document.createElement('listitem')
		row.setAttribute('value', myPropUri)
		row.setAttribute('tooltiptext', myValueUri)
		if len(myProp) >20:
			myValue = myValue[0:17]+"..."
		if len(myProp) >20:
			myValue = myValue[0:17]+"..."
		
		cell = document.createElement('listcell')
		cell.setAttribute('label', myProp)
		row.appendChild(cell)

		cell = document.createElement('listcell')
		cell.setAttribute('label', myValue)
		row.appendChild(cell)

		mylist.appendChild(row);
	AnnoOnLoad()

def clickOnProperty():
	PROPLIST = document.getElementById("propList")
	theProperty = PROPLIST.selectedItem.getAttribute("value")
	theValue = PROPLIST.selectedItem.getAttribute("tooltiptext")
	#Show related resources
	window.openDialog("chrome://nepomuk/content/relatedRes.xul","dlg","height=400,width=300",theProperty,theValue)

def removeCurrent():
	
	current_url = window.content.document.location.href
	
	#need some improvement
	t = document.getElementById("SBtagTree")
	
	cellIndex = 0;
	cellText = t.view.getCellText(t.currentIndex, t.columns.getColumnAt(cellIndex));
	
	document_uri = document.NEPO.interface.getAntecedent(PIMO_GROUNDINGOCCURRENCE, current_url)
	if document_uri == None:
		return 1
	
	document.NEPO.nao.removeTag(document_uri,cellText)
	
	currentCell = t.view.getItemAtIndex(t.currentIndex)
	currentCell.parentNode.removeChild(currentCell)
	
	logger.debug("The tag "+cellText+" has been deleted!")
	getTags()

###############################Deal with Ontology Management######################################
import os
import pickle


ONTOLOGIES_YES = document.getElementById("ontologies-yes")
ONTOLOGIES_NO = document.getElementById("ontologies-no")
LBL_SELECTED_ONTO = document.getElementById("selected_ontology")
ONTO_URL = document.getElementById("ontology_url")


logger = logging.getLogger("xul_ontologies")


############################################################


def onLoad():
	getProps()
	try:
		watchedOnLoad()
	except Exception, e:
		print """Error, Problem accessing the needed elements to use Nepomuk Foxtrot. Please check that nepomukserver is up and running (Error is "%s").""" % e

############################################################

def watchedOnLoad():
	
	logger.debug("onLoad()")
	
	
	document.page_uri = window.content.document.location.href
	
	# attach TheNepomukWhisperer to the document
	from the_nepomuk_whisperer import TheNepomukWhisperer
	document.NEPO = TheNepomukWhisperer(ONTOLOGIES_STORAGE_FILE)
	
	# retrieve the data possibly stored in PATH_CONTENT/ontologies.pkl
	
	ontos_yes = document.NEPO.ontos_mgr.getSelectedOntologies()
	
	# use the retrieved (or not) set along with a request on the database
	ontologies = document.NEPO.ontos_mgr.getAllOntologies()
	
	# add the ontologies registered in ontologies.pkl.
	for ontology in ontos_yes:
		if ontology in ontologies:
			name = document.NEPO.interface.getImage(ontology, NAO_HASDEFAULTNAMESPACEABBREVIATION)
			if name == None:
				name = document.NEPO.pimo.getName(ontology)
			ONTOLOGIES_YES.appendItem(name, ontology)
			ontologies.remove(ontology)
	
	# add other ontologies: the "not selected" ones and the new ones from the database.
	for ontology in ontologies:
		
		name = document.NEPO.interface.getImage(ontology, NAO_HASDEFAULTNAMESPACEABBREVIATION)
		if name == None:
			name = document.NEPO.pimo.getName(ontology)
		
		if ontology in ontos_yes == 1:
			ONTOLOGIES_YES.appendItem(name, ontology)
		else:
			ONTOLOGIES_NO.appendItem(name, ontology)
	
	ONTOLOGIES_NO.selectedIndex = 0

############################################################

def finish():
	
	logger.debug("finish()")
	
	ontos_yes = set()
	
	for i in range(ONTOLOGIES_YES.childNodes.length):
		
		ontology = ONTOLOGIES_YES.childNodes.item(i).getAttribute("value")
		# register this ontology in the external file for persistence
		ontos_yes.add(ontology)
		# actually load the selected ontologies in database
		document.NEPO.ontos_mgr.importOntology(ontology)
	
	f = file(ONTOLOGIES_STORAGE_FILE, "w")
	pickle.dump(ontos_yes, f)
	f.close()

############################################################

def ontologiesYesClick():
	selValue = ONTOLOGIES_YES.selectedItem.getAttribute("value")
	if ONTOLOGIES_YES.selectedIndex != -1:
		logger.debug(ONTOLOGIES_YES.selectedItem.getAttribute("label") + " <--> " + ONTOLOGIES_YES.selectedItem.getAttribute("value"))
		LBL_SELECTED_ONTO.setAttribute("tooltiptext", selValue)
		selValue = selValue[0:20]+"..."
		LBL_SELECTED_ONTO.setAttribute("value", selValue)
		
def ontologiesYesDblClick():
	selValue = ONTOLOGIES_YES.selectedItem.getAttribute("value")
	if ONTOLOGIES_YES.selectedIndex != -1:
		logger.debug(ONTOLOGIES_YES.selectedItem.getAttribute("label") + " <--> " + ONTOLOGIES_YES.selectedItem.getAttribute("value"))
		LBL_SELECTED_ONTO.setAttribute("tooltiptext", selValue)
		window.openDialog("chrome://nepomuk/content/ontoTree.xul","dlg","height=600,width=560",selValue)
		selValue = selValue[0:20]+"..."
		LBL_SELECTED_ONTO.setAttribute("value", selValue)

############################################################

def ontologiesNoClick():
	selValue = ONTOLOGIES_NO.selectedItem.getAttribute("value")
	if ONTOLOGIES_NO.selectedIndex != -1:
		logger.debug(ONTOLOGIES_NO.selectedItem.getAttribute("label") + " <--> " + ONTOLOGIES_NO.selectedItem.getAttribute("value"))
		LBL_SELECTED_ONTO.setAttribute("tooltiptext", selValue)
		selValue = selValue[0:20]+"..."
		LBL_SELECTED_ONTO.setAttribute("value", selValue)
		
def ontologiesNoDblClick():
	selValue = ONTOLOGIES_NO.selectedItem.getAttribute("value")
	if ONTOLOGIES_NO.selectedIndex != -1:
		logger.debug(ONTOLOGIES_NO.selectedItem.getAttribute("label") + " <--> " + ONTOLOGIES_NO.selectedItem.getAttribute("value"))
		LBL_SELECTED_ONTO.setAttribute("tooltiptext", selValue)
		window.openDialog("chrome://nepomuk/content/ontoTree.xul","dlg","height=600,width=560",selValue)
		selValue = selValue[0:20]+"..."
		LBL_SELECTED_ONTO.setAttribute("value", selValue)

############################################################

def add():
	
	if ONTOLOGIES_NO.selectedIndex == -1:
		return 1
	
	# remove element from ONTOLOGIES_NO
	index = ONTOLOGIES_NO.selectedIndex
	elt = ONTOLOGIES_NO.removeChild(ONTOLOGIES_NO.getItemAtIndex(ONTOLOGIES_NO.selectedIndex))
	
	# select new index in ONTOLOGIES_NO
	if index == ONTOLOGIES_NO.childNodes.length:
		ONTOLOGIES_NO.selectedIndex = ONTOLOGIES_NO.childNodes.length-1
	else:
		ONTOLOGIES_NO.selectedIndex = index
	
	# add element into ONTOLOGIES_YES
	if ONTOLOGIES_YES.selectedIndex != -1:
		ONTOLOGIES_YES.insertBefore(elt, ONTOLOGIES_YES.selectedItem)
	else:
		ONTOLOGIES_YES.appendChild(elt)
	
	# select new index in ONTOLOGIES_YES
	ONTOLOGIES_YES.selectedIndex = ONTOLOGIES_YES.getIndexOfItem(elt)
	
	return 0
	
############################################################

def remove():
	
	if ONTOLOGIES_YES.selectedIndex == -1:
		return 1
	
	# remove element from ONTOLOGIES_YES
	index = ONTOLOGIES_YES.selectedIndex
	elt = ONTOLOGIES_YES.removeChild(ONTOLOGIES_YES.getItemAtIndex(ONTOLOGIES_YES.selectedIndex))
	
	# select new index in ONTOLOGIES_YES
	if index == ONTOLOGIES_YES.childNodes.length:
		ONTOLOGIES_YES.selectedIndex = ONTOLOGIES_YES.childNodes.length-1
	else:
		ONTOLOGIES_YES.selectedIndex = index
	
	# add element into ONTOLOGIES_NO
	if ONTOLOGIES_NO.selectedIndex != -1:
		ONTOLOGIES_NO.insertBefore(elt, ONTOLOGIES_NO.selectedItem)
	else:
		ONTOLOGIES_NO.appendChild(elt)
	
	# select new index in ONTOLOGIES_NO
	ONTOLOGIES_NO.selectedIndex = ONTOLOGIES_NO.getIndexOfItem(elt)
	
	return 0

############################################################

def up():
	
	index = ONTOLOGIES_YES.selectedIndex
	if (index == 0) or (index == -1):
		return 1
	
	elt1 = ONTOLOGIES_YES.getItemAtIndex(index - 1)
	elt2 = ONTOLOGIES_YES.getItemAtIndex(index)
	
	ONTOLOGIES_YES.removeChild(elt2)
	ONTOLOGIES_YES.insertBefore(elt2, elt1)
	
	ONTOLOGIES_YES.selectedIndex = index - 1
	
	return 0

############################################################

def down():
	
	index = ONTOLOGIES_YES.selectedIndex
	if (index == ONTOLOGIES_YES.childNodes.length - 1) or (index == -1):
		return 1
	
	elt1 = ONTOLOGIES_YES.getItemAtIndex(index)
	elt2 = ONTOLOGIES_YES.getItemAtIndex(index + 1)
	
	ONTOLOGIES_YES.removeChild(elt2)
	ONTOLOGIES_YES.insertBefore(elt2, elt1)
	
	ONTOLOGIES_YES.selectedIndex = index + 1
	
	return 0

############################################################

def loadOnto():
	
	onto_url = ONTO_URL.value
	ONTO_URL.value = ""
	logger.debug("onto_url = %s" % onto_url)
	
	document.NEPO.ontos_mgr.importOntology(onto_url)

############################################################

def refreshOntos():
	
	# clear both lists
	while ONTOLOGIES_YES.childNodes.length != 0:
		ONTOLOGIES_YES.removeChild(ONTOLOGIES_YES.firstChild)
	
	while ONTOLOGIES_NO.childNodes.length != 0:
		ONTOLOGIES_NO.removeChild(ONTOLOGIES_NO.firstChild)
	
	# reload ontologies
	onLoad()
	
##########################Annotation Management#############################
import copy
import pickle
import os
from exceptions import Exception
import threading

from ontology_manager import OntologyManager

from followed_thread import FollowedThread



# page objects
OTHERS_HINT = document.getElementById("othersHint")
OTHERS_LIST = document.getElementById("othersList")
OTHERS_VALUE = document.getElementById("othersValue")
OTHERS_AREOBJECTS = document.getElementById("othersAreObjects")
OTHERS_MORE = document.getElementById("btMore")
OTHERS_FILTER = document.getElementById("othersFilter")
OTHERS_PROGRESS = document.getElementById("progressOthers")

CURRENT_THING_NAME = document.getElementById("currentThingName")
PROPERTIES_FILTER = document.getElementById("propsFilter")
PROPERTIES_LIST = document.getElementById("propertiesList")
LABEL_PAGE_URI = document.getElementById("labelPageURL")
PROPS_FILTER = document.getElementById("propsFilter")

URI_DISPLAY = document.getElementById("uri_display")
STATEMENT_BT = document.getElementById("btCreateStatement")

# constants
NO_EXISTING_NAME = "No existing name, enter one."
PRISTINE_PROPS_FILTER = "Type your filter here..."
PROPERTIES_FILTER.setAttribute("value", PRISTINE_PROPS_FILTER)

PRISTINE_OTHERS_FILTER = "Search element by name..."
OTHERS_FILTER.setAttribute("value", PRISTINE_OTHERS_FILTER)

THREAD_PROPS = "PropertiesListClick"

OTHERS_MODE_PROPERTY = 0
OTHERS_MODE_ELTS_SEARCH = 1

logger = logging.getLogger("xul_pimo")



"""
~~~~~~~~~~~~~~~~~~~~ DOCUMENT ATTRIBUTES ~~~~~~~~~~~~~~~~~~~
These attributes are set at page load (onLoad() method and used in the whole page.

- document.NEPO : TheNepomukWhisperer
	* Used to call all the Nepomuk methods, through document.NEPO.interface|nao|pimo etc.

- document.page_thing_name : String
	* Used to remember the name found at the page load. Useful to detect if the user has changed the page name, and then register the possible change in Nepomuk.

- document.page_uri : String
	* Used to remember the page URI.

- document.properties : list([string(name), string(uri)])
	* Used to contain the current list of properties to be displayed in the XUL:listbox.

- document.current_property_uri : String
	* The property of which the possible range elements are currently displayed.

- document.refresh_props_list_timeout_id
	* The current value that identifies the window timeout used to refresh the props list.

- document.others : list([string(name), string(uri)])
	* Used to contain the current list of elements to be displayed in the XUL:listbox.

- document.others_priority_level : Integer
	* Used to set at which priority level the others list is built.

- document.others_mode : DOCUMENT_MODE (see possible modes in constants of this page)

- document.thread_props : the thread currently running (if it exists) which gets the other elements to display.

"""
document.page_uri = None

document.properties = list()
document.current_property_uri = None
document.refresh_props_list_timeout_id = None

document.others = list()
document.others_priority_level = None

document.mode = OTHERS_MODE_PROPERTY

document.thread_props = None




############################################################

def AnnoOnLoad():
	onFocus()
	try:
		watchedAnnoOnLoad()
	except Exception, e:
		print "Error in AnnoOnload() of neposbar.py, Problem accessing the needed elements to use Nepomuk Foxtrot. Please check that nepomukserver is up and running (Error is \"%s\")." % e

############################################################
	
def watchedAnnoOnLoad():
	
	logger.debug("AnnoOnLoad()")
	
	document.page_uri = window.content.document.location.href
	
	# attach TheNepomukWhisperer to the document
	from the_nepomuk_whisperer import TheNepomukWhisperer
	document.NEPO = TheNepomukWhisperer(ONTOLOGIES_STORAGE_FILE)
	
	# Display the URL of the web page
	LABEL_PAGE_URI.setAttribute("value", document.page_uri)
	
	
	# set the page thing name
	document.page_thing_name = document.NEPO.pimo.getName(document.page_uri)
	if document.page_thing_name == None:
		CURRENT_THING_NAME.value = NO_EXISTING_NAME
	else:
		CURRENT_THING_NAME.value = document.page_thing_name

############################################################

def onFocus():
	
	logger.debug("onFocus()")
	
	ontos_mgr = OntologyManager(document.NEPO.interface, ONTOLOGIES_STORAGE_FILE)
	ontologiesList = ontos_mgr.getSelectedOntologies()
	# Load the propertiesList.
	named_properties = document.NEPO.pimo.getAllPropertiesOf(ontologiesList)
	
	# clear the props list
	document.properties = list()
	
	# clear the XUL properties list
	while PROPERTIES_LIST.childNodes.length != 0:
		PROPERTIES_LIST.removeChild(PROPERTIES_LIST.firstChild)
	
	# add all the retrieved properties in properties
	for named_property in named_properties:
		document.properties.append([named_property[0], named_property[1]])
		PROPERTIES_LIST.appendItem(named_property[0], named_property[1])
	
	logger.debug("nb properties = "+str(len(document.properties)))
	

############################################################

# This is an ugly method which allows to look for a thread ending. This could be far better implemented with a threads-signals-notify-etc. system that is actually available in Python. The problem is that the DOM is not thread safe, so it cannot be accessed by a thread without high and random risk of crash...
def refreshOthersList():
	
	logger.debug("***refreshOthersList()***")
	
	# Check whether THREAD_PROPS is still running.
	threads = threading.enumerate()
	for thread in threads:
		if thread.getName() == THREAD_PROPS:
			document.refresh_props_list_timeout_id = window.setTimeout(500, refreshOthersList)
			return
	logger.debug(THREAD_PROPS + " has stopped running")
	
	endingMethod()

############################################################

# Create new Statement according to the current Property
def createStatement(event):
	if event.button != 0: # not a left-click
		return 0
	
	if PROPERTIES_LIST.selectedIndex == -1:
		return 1
	logger.debug("***refreshOthersList()***")
	selValue = PROPERTIES_LIST.selectedItem.value

	window.openDialog("chrome://nepomuk/content/createStatement.xul","dlg","height=420,width=600",selValue)
	

############################################################

def endingMethodForClick():
	
	requestTerminated()
	# add the elements in the XUL list
	for named_elt in document.others:
		OTHERS_LIST.appendItem(named_elt[0], named_elt[1])

############################################################

def endingMethodForKeyUp():
	
	requestStopped()
	# add the elements in the XUL list
	for named_elt in document.others:
		OTHERS_LIST.appendItem(named_elt[0], named_elt[1])

############################################################

def beginningMethod():
	
	# Clear the list of other possible elements
	while OTHERS_LIST.childNodes.length != 0:
		OTHERS_LIST.removeChild(OTHERS_LIST.firstChild)
	
	document.current_property_uri = PROPERTIES_LIST.selectedItem.getAttribute("value")
	#logger.debug("property_uri = "+property_uri)
	
	if document.NEPO.pimo.isDescribingProperty(document.current_property_uri):
		logger.debug("describingProperty")
		othersAreValues()
		return False
	else:
		logger.debug("non-describingProperty")
		othersAreObjects()
		othersMode(OTHERS_MODE_PROPERTY)
		return True

############################################################

def propertiesListClick(event):
	
	# TODO: allow the display of others_list with any button to maintain coherence between properties_list.selectedItem and the elements displayed in others_list (do this only when there are threads!)
	if event.button != 0: # not a left-click
		return 0
	
	if PROPERTIES_LIST.selectedIndex == -1:
		return 1
	
	URI_DISPLAY.setAttribute("tooltiptext", PROPERTIES_LIST.selectedItem.value)
	URI_DISPLAY.setAttribute("value", PROPERTIES_LIST.selectedItem.value[0:18]+"...")
	STATEMENT_BT.setAttribute("hidden", "false")
	
	document.others_priority_level = 0
	
	if document.thread_props != None:
		document.thread_props.kill()
	
	if beginningMethod(): # non-describing property
		requestRun()
		document.thread_props = FollowedThread(window, THREAD_PROPS, getOtherElements, (document.current_property_uri,), endingMethodForClick)
		document.thread_props.run()
	else: # describing property
		requestStopped()
		document.thread_props = None
		logger.debug("No need to start THREAD_PROPS.")

############################################################

def moreResults():
	
	if document.current_property_uri == None:
		return 1 # there is no current property
	
	if document.thread_props != None:
		document.thread_props.kill()
	
	othersMode(OTHERS_MODE_PROPERTY)
	
	requestRun()
	document.others_priority_level += 1
	document.thread_props = FollowedThread(window, THREAD_PROPS, getOtherElements, (document.current_property_uri,), endingMethodForClick)
	document.thread_props.run()

############################################################

# This method is meant to be called in a separate thread.
def getOtherElements(property_uri):
	
	logger.debug("getOtherElements(%s, %s)", property_uri, document.others_priority_level)
	
	document.others = list()
	
	ontologies = document.NEPO.ontos_mgr.getOntologiesAtLevel(document.others_priority_level)
	if ontologies == None:
		logger.debug("No more results!")
		return 1
	
	# Generate the list of other possible elements to relate
	while (True):
		
		named_elements = document.NEPO.pimo.getPossibleRangeElementsFor(property_uri, document.others_priority_level, ontologies)
		
		if named_elements == []:
			logger.debug("No new element found at level %s, moving on to next level." % document.others_priority_level)
			document.others_priority_level += 1
			getOtherElements(property_uri)
			return
		else:
			break
	
	if named_elements == None:
		logger.debug("No more results!") #PROMPTS.alert(window, "Information", "There are not any more results.") (not possible since the DOM is not thread safe!)
	else:
		logger.debug("named_elements = %s" % named_elements)
		for named_elt in named_elements:
			document.others.append([named_elt[0], named_elt[1]])

############################################################

def propsFilterFocus():
	
	logger.debug("focus")
	if PROPERTIES_FILTER.value == PRISTINE_PROPS_FILTER:
		PROPERTIES_FILTER.value = ""

############################################################

def propsFilterKeyUp():
	
	filter_string = PROPS_FILTER.value
	
	# Clear the properties list.
	while PROPERTIES_LIST.childNodes.length != 0:
		PROPERTIES_LIST.removeChild(PROPERTIES_LIST.firstChild)
	
	# Add properties that contains the filter text to the properties list (case insensitive).
	logger.debug("filter")
	#logger.debug("properties = "+str(len(properties)))
	
	for named_property in document.properties:
		i = named_property[1].lower().find(filter_string.lower())
		#logger.debug(named_property[0]+".lower().find("+filter_string+".lower())"+str(i))
		if i != -1:
			PROPERTIES_LIST.appendItem(named_property[0], named_property[1])

############################################################

def othersListClick():
	
	if OTHERS_LIST.selectedIndex == -1:
		return 1
	
	property_uri = OTHERS_LIST.selectedItem.getAttribute("value")
	URI_DISPLAY.setAttribute("tooltiptext", property_uri)
	URI_DISPLAY.setAttribute("value", property_uri[0:18]+"...")

############################################################

def othersFilterFocus():
	
	if OTHERS_FILTER.value == PRISTINE_OTHERS_FILTER:
		OTHERS_FILTER.value = ""

############################################################

def othersFilterKeyUp():
	
	if document.thread_props != None:
		document.thread_props.kill()
	
	othersMode(OTHERS_MODE_ELTS_SEARCH)
	
	# Clear the others list.
	while OTHERS_LIST.childNodes.length != 0:
		OTHERS_LIST.removeChild(OTHERS_LIST.firstChild)
	
	filter_string = OTHERS_FILTER.value
	if len(filter_string) < 2:
		document.thread_props = None
		requestStopped()
		return 0
	else:
		requestRun()
		document.thread_props = FollowedThread(window, THREAD_PROPS, getResourcesMatchingFilter, (filter_string,), endingMethodForKeyUp)
		document.thread_props.run()

############################################################

def getResourcesMatchingFilter(filter_string):
	
	document.others = []
	resources = document.NEPO.interface.getAllNonPropertyObjects(filter_string)
	logger.debug("len(resources) = %s" % len(resources))
	
	i = 0
	for resource in resources:
		if i > 20:
			break # for loop
		i += 1
		name = document.NEPO.pimo.getName(resource)
		document.others.append([name, resource])

############################################################

def delProp():
	
	property_name = PROPERTIES_LIST.selectedItem.getAttribute("label")
	answer = PROMPTS.confirm(window, "Confirmation", "Are you sure you want to delete the property named \"" + property_name + "\"?")
	
	if answer:
		deleteProperty()
	else:
		pass

############################################################

def deleteProperty():
	
	property_uri = PROPERTIES_LIST.selectedItem.getAttribute("value")
	property_name = PROPERTIES_LIST.selectedItem.getAttribute("label")
	logger.debug("property_uri="+property_uri)
	
	try:
		if document.NEPO.pimo.isDescribingProperty(property_uri):
			logger.debug("***	 describingProperty	 ***")
			document.NEPO.pimo.deleteDescribingProperty(property_uri)
		else:
			logger.debug("*** non-describingProperty ***")
			document.NEPO.pimo.deleteProperty(property_uri)
		
		PROMPTS.alert(window, "Information", "The property named \"" + property_name + "\" has properly been deleted.")
	
	except CanNotException, e:
		PROMPTS.alert(window, "Error", str(e))
	
############################################################

def othersAreObjects():
	
	OTHERS_HINT.setAttribute("value", "Other possible elements:")
	OTHERS_LIST.setAttribute("hidden", "false")
	OTHERS_MORE.setAttribute("hidden", "false")
	OTHERS_FILTER.setAttribute("hidden", "false")
	
	OTHERS_VALUE.setAttribute("hidden", "true")

############################################################

def othersAreValues():
	
	OTHERS_HINT.setAttribute("value", "Enter a value:")
	OTHERS_LIST.setAttribute("hidden", "true")
	OTHERS_MORE.setAttribute("hidden", "true")
	OTHERS_FILTER.setAttribute("hidden", "true")
	
	OTHERS_VALUE.setAttribute("hidden", "false")

############################################################

def requestRun():
	
	OTHERS_MORE.hidden = True
	OTHERS_MORE.disabled = True
	OTHERS_PROGRESS.hidden = False

############################################################

def requestStopped():
	
	OTHERS_PROGRESS.hidden = True

############################################################

def requestTerminated():
	
	requestStopped()
	
	OTHERS_MORE.hidden = False
	OTHERS_MORE.label = "More"
	
	# display information for the user to know what the next level (more button) is about.
	priority_level_description = document.NEPO.ontos_mgr.getPriorityLevelDescription(document.others_priority_level + 1)
	
	if priority_level_description != None:
		OTHERS_MORE.setAttribute("tooltiptext","More (search in %s)" % priority_level_description)
		OTHERS_MORE.disabled = False
	else:
		OTHERS_MORE.label = "no more results"
		OTHERS_MORE.disabled = True

############################################################

def othersMode(mode):
	
	document.mode = mode
	
	if mode == OTHERS_MODE_PROPERTY:
		name =  document.NEPO.pimo.getName(document.current_property_uri)
		val = "Elements compatible with relation \"%s\":" % name
		OTHERS_HINT.setAttribute("tooltiptext", val)
		OTHERS_HINT.setAttribute("value", val[0:18]+"...")
		
	elif mode == OTHERS_MODE_ELTS_SEARCH:
		val = "Elements containing \"%s\":" % OTHERS_FILTER.value
		OTHERS_HINT.setAttribute("tooltiptext", val)
		OTHERS_HINT.setAttribute("value", val[0:18]+"...")
		OTHERS_MORE.disabled = True
	
	else:
		logger.debug("OTHERS_HINT.value = ??? (%s is not known as a mode!)" % mode)

############################################################

def addRelation():
	
	# different checkings
	if (CURRENT_THING_NAME.value == NO_EXISTING_NAME) or (CURRENT_THING_NAME.value == ""):
		PROMPTS.alert(window, "Missing information", "Please enter a thing name for the current page.")
		return 1
	
	property_uri = None
	if PROPERTIES_LIST.selectedIndex != -1:
		property_uri = PROPERTIES_LIST.selectedItem.getAttribute("value")
		property_name = PROPERTIES_LIST.selectedItem.getAttribute("label")
	else:
		PROMPTS.alert(window, "Missing information", "Select a property from the list to relate your elements.")
		return 1
	
	try:
		if OTHERS_LIST.getAttribute("hidden") == "true":
			
			# valued description
			if OTHERS_VALUE.value == "":
				PROMPTS.alert(window, "Missing information", "Please enter a value to describe \"" + CURRENT_THING_NAME.value + "\" with the property \"" + property_name + "\".")
				return 1
			else:
				# register the name given for the current web page
				thing_uri = document.NEPO.interface.registerAndReify(document.page_uri, NFO_WEBSITE, CURRENT_THING_NAME.value)
				document.NEPO.pimo.setValuedDescription(thing_uri, property_uri, OTHERS_VALUE.value)
			
		else:
			
			# object-to-object relation
			object_uri = None
			if OTHERS_LIST.selectedIndex == -1:
				PROMPTS.alert(window, "Missing information", "Select an object from the objects list on the right to relate with \"" + CURRENT_THING_NAME.value + "\".")
				return 1
			else:
				# register the pimo:Thing name given for the current web page
				thing_uri = document.NEPO.interface.registerAndReify(document.page_uri, NFO_WEBSITE, CURRENT_THING_NAME.value)
				object_uri = OTHERS_LIST.selectedItem.getAttribute("value")
				document.NEPO.pimo.addRelation(thing_uri, property_uri, object_uri)
		
		PROMPTS.alert(window, "Information", "The relation has properly been added.")
		getProps()
	
	except CanNotException, e:
		PROMPTS.alert(window, "Missing information", str(e))
	
	#except TypeError, e:
		#PROMPTS.alert(window, "Bad type", str(e))

############################################################

def onUnload():
	
	logger.debug("onUnload()")
	if document.thread_props != None:
		document.thread_props.kill()
